#include <stdio.h>

int main()
{
    int arr[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    int i, j;

    // 定义一个指向"包含4个int元素的数组"的指针
    // 声明p是一个指向数组的指针，具体指向"包含4个int元素的数组"（即二维数组的一行）
    int (*p)[4];
    // 将指针p指向二维数组arr的首行地址
    p = arr;

    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 4; j++)
        {
            // printf("arr[%d][%d] = %d ", i, j, arr[i][j]);

            /*
            核心：指针访问数组元素
            - *(*(p + i) + j)是通过指针运算访问arr[i][j]的等价写法，具体拆解：
            - p + i：指针p向后移动i行（因p指向一行，每次加1移动一行），指向第i行。
            - *(p + i)：解引用得到第i行的数组（数组名会退化为指向首元素的指针，即第i行第0列元素的地址）。
            - *(p + i) + j：指针向后移动j个元素（每个元素是int类型），指向第i行第j列元素。
            - *(*(p + i) + j)：解引用得到第i行第j列元素的值，等价于arr[i][j]。
            */
            printf("arr[%d][%d] = %d ", i, j, *(*(p + i) + j));
        }
        printf("\n");
    }

    return 0;
}

/*
out:

arr[0][0] = 1 arr[0][1] = 2 arr[0][2] = 3 arr[0][3] = 4
arr[1][0] = 5 arr[1][1] = 6 arr[1][2] = 7 arr[1][3] = 8
arr[2][0] = 9 arr[2][1] = 10 arr[2][2] = 11 arr[2][3] = 12
*/